<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>变量的解构与赋值</title>
</head>
<body>
<div></div>
<script>
    /* 数组解构-模式匹配 */
    // let [a,b,c] = [1,2,3]
    // let [x,y, ...z] = ['a','b','c','d','e']
    // let [aa,bb,...cc] = ['1']
    // let [, , three] = [1,2,3]

    /* 不匹配 */
    // let [a,[b],d]=[1,[2,3],4] // 1,2,4

    /* SET解构 */
    // let[x,y,z] = new Set(['a','b','c'])

    /*默认值*/
    // let [x=1] = [undefined] // 1
    // let [y=1] = [null] //null

    // function foo() {    let[x=8, y=x] = []; // 8
    // let[x=y, y=9] = []; //报错 x的默认值为y时，y还没有声明
    // console.log(x)

    /*惰性求值*/
    //     console.log(111);
    // }
    // var [x=foo()]= [1] // x能取到值，foo()不会执行
    // console.log(x)

    /*对象解构赋值*/
    //let { bar, foo } = {bar: 'aa', foo: 'bb'}; //变量名必须与属性名相同
    //否则
    // let {first:baz} = {first: 'hello',last: 'world' }; // hello
    // 实际写法真正赋值的是后者
    // let {foo:foo,bar:bar} = {foo: 'hello',bar:'world'};

    /*嵌套解构的对象*/
    // let obj = {
    //     p: ['hello', {y: 'world'}]
    // }
    // let {p: [x, {y}]} = obj // hello world

    // const node = {
    //     loc: {
    //         start: {
    //             column: '111',
    //             line: '222'
    //         }
    //     }
    // };
    // let {loc, loc: { start }, loc: {start : {line}}} = node

    /*嵌套赋值*/
    // let obj = {};
    // let arr = [];
    // ({ foo: obj.prop, bar:arr[0] } = { foo:123, bar:true }); // {prop:123},[true]

    /*对象解构指定默认值*/
    // let { x=3 } = {}; // 3
    // let {x: y=3 } = {} // y->3
    // let {x: y=3} = { x: 5 } //y->5

    // let x;
    // ({x} = {x: 1}); // {x}是个代码块 报错
    // ({} = 'abc'); //等号左边允许不放置任何东西，但必须在圆括号内

    /*数组对象解构-属性名表达式*/
    // let arr = [1,2,3];
    // let { 0: first, [arr.length-1]: last} = arr; // [arr.length-1]为2 对应的值是3

    /*字符串解构赋值*/
    // let [a,b,c,d,e] = 'hello'; // a->h, b->e, c->l ... //字符串被转换成类似数组的对象
    // let {length: len} = 'hello';

    /*数值和布尔值解构赋值*/
    // let {toString: s} = 123;  // 等号右边是数值和布尔值，则会先转为对象。
    // s = Number.prototype.toString; //ƒ toString() { [native code] }
    // let {toString: s} = true;
    // s = Boolean.prototype.toString; //ƒ toString() { [native code] }
    //undefined 和 null 无法转换为对象所以会报错
    // let { prop: props } = null // TypeError
    // let { prop: props } = undefined // TypeError

    /*函数参数的解构赋值*/
    // function add([x, y]){
    //     return x + y;
    // };
    // add([1, 2])

    //let arr = [[1,2],[3,4]]; // 二维数组的解构
    //arr.map(([a,b]) => { console.log(a+b)} )

   /*函数参数解构-为 变量 指定默认值*/
    // function fun({x=0,y=0} = {}) {
    //     return [x,y];
    // };
    // fun({x:3,y:5}) // 3,5
    //fun(); //0,0
    /*为函数 参数 指定默认值*/
    // function fun({x,y} = {x:0,y:0}) {
    //     return [x,y]
    // }
    // fun({x: 3}) //x->3,y->undefined

    /*undefined会触发 函数参数 的默认值*/
    // [1,undefined,'aa'].map((x='yes') => console.log(x)); // x-> [1,'yes','aa']

    /*声明变量不能使用圆括号*/
    // let {o:{(p):p}} = {o: {p:2}} // 报错
    /*函数参数也属于变量声明不能使用圆括号*/
    // function fun([(z)]) {return z;} // 报错
    /*赋值语句的模式不能使用圆括号*/
    // ({p:a}) = {p:'11'}; // SyntaxError
    /*非模式部分可以使用圆括号的情况*/
    // [(b)] = [3]; // 3

    /*用途*/
    /*1.交换变量的值*/
    // let x=1;
    // let y=2;
    // [x,y] = [y,x] // x->2, y=1
    /*2.函数只能返回一个值，如果要返回多个只能放在数组或对象中，可以使用解构赋值获取返回的多个值*/
    // function fun() {
    //     return [1,2,3]
    // }
    // const {a,b,c} = fun()
    // console.log(fun());

    /*3.函数参数的定义*/
    // function f([x, y, z]) { };f([1,2,3]) //参数名与变量名可以更好的对应
    // function f({x,y,z}){return {x,y,z}};console.log(f({z:3,y:2,x:0}));

    /*4,提取JSON数据*/
    // let jsonObj = {
    //     id: '01',
    //     name: 'zhang',
    //     age: 11
    // }
    // let { id, name, age } = jsonObj

    /*5.函数参数默认值*/
    // jquery.ajax = function (url, { //指定参数的默认值
    //     async= true,
    //     beforeSend = function() {},
    //     cache=true
    // } = {}) {}

    /*6.遍历Map结构*/
    // const map = new Map();
    // map.set('first', 'hello');
    // map.set('second', 'world');
    //
    // for(let [key,value] of map) { // 获取键名和键值
    //     console.log(key +  '-is-'  + value)
    // }
    // for(let [value] of map) {
    //     console.log(value)
    // }
    // console.log(map)

    /*7.输入模块的指定方法*/
    // const { SourceMapConsumer, SourceNode } = require("source-map");
</script>
</body>
</html>